在上一篇提到如何以二值化的圖片抓出contours,
但不是每個contour都是我們需要的,
這通常用在擷取我們感興趣的區域(Region of Interest,簡稱ROI),
一般來說,我們可以使用幾個contour的特徵來進行篩選,
如contour的面積、位置以及數值等等,
今天就跟大家介紹關於以contour抓取ROI的方法,
首先回到上一篇最後的結果,我們有抓出一張LOGO圖片中所有的contours,
那我們要怎麼去把單獨分離或者是抓出特徵數值呢?
首先我們可以加入以下code來抓出contour的面積跟中心點,
#將二值化的圖片放到findContours()中
contours,hierarchy = cv.findContours(binary,cv.RETR_LIST,cv.CHAIN_APPROX_SIMPLE)
n = len(contours)
for i in range(n):
M = cv.moments(contours[i])
area = M['m00']
cx = int(M['m10']/M['m00'])
cy = int(M['m01']/M['m00'])
center = tuple((cx,cy))
print('輪廓編號%d,面積大小%d,中心點%s'%(i,area,str(center)))
這樣就可以依照print出來的結果來看目標圖片中的輪廓特徵狀況,
結果如下圖所示:
這邊的面積計算方式,是以contour所包裹的像素數量做計算的,
用面積作為輪廓篩選的標準,在簡單的輪廓挑選中是非常方便使用的,
在範例中,是以area>0作為篩選標準,因此可以看到所有的輪廓面積、中心點,
問題來了,從輪廓編號我們並無法標定出想要的輪廓是哪個,
因此有幾個辦法,即透過面積與中心點,先進行初步篩選,
同時標定出個別輪廓的中心點位置來加以判斷,方法如下:
#建立空白圖片
empty = np.ones(img.shape,dtype=np.uint8)*255
total_area = img.shape[0]*img.shape[1]
font = cv.FONT_HERSHEY_COMPLEX
print(total_area)
n = len(contours)
for i in range(n):
M = cv.moments(contours[i])
area = M['m00']
if area/total_area>0.15 and area/total_area<0.50:#若面積大於總面積的15%且小於50%
cx = int(M['m10']/M['m00'])
cy = int(M['m01']/M['m00'])
center = tuple((cx,cy))
if cx>img.shape[1]*0.25 and cx<img.shape[1]*0.75:
cv.putText(empty,'. no.='+str(i),center,font,2,(0,0,255),1)
print('輪廓編號%d,面積大小%d,中心點%s'%(i,area,str(center)))
#將輪廓描繪在複製圖上
copy = cv.drawContours(empty,contours[i],-1,(255,0,0),2)
上面是先計算圖片總面積,
以img.shape[0]及img.shape[1]抓出圖片高跟寬,
兩者相乘即為圖片總面積,
接著再以個別的輪廓面積計算總面積佔比,大於15%且小於50%者進行下一步,
中心點的位置篩選則是以cx作為x座標方向的位置判斷,
若中心點位於x方向25%-75%的位置之間,則進行下一步,
利用cv.putText()來標定文字在輪廓中心點的位置,需要的參數是:
1.要標定文字的圖片
2.要標定的文字內容
3.標定的座標位置
4.字型設定
5.字體大小
6.字體顏色
7.字體粗細
結果圖如下:
以上是用contour面積與中心點進行輪廓篩選的簡易辦法,
如此一來便可將畫面中具有明顯輪廓的部分標定出來,
下一篇將會提到如何以圖片中的特定顏色標定ROI。